﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Windows.Threading;
using System.Windows.Media.Animation;

namespace Save_the_Humans__recode_
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 
    public partial class MainWindow : Window
    {
        Random random = new Random();
        DispatcherTimer alienTimer = new DispatcherTimer();
        DispatcherTimer hornAlienTimer = new DispatcherTimer();
        DispatcherTimer targetTimer = new DispatcherTimer();
        bool humanCaptured = false; byte countScore = 0;
        double oriHumanX, oriHumanY, oriTargetX, oriTargety;

        const byte winScore = 10;
        const byte FAST = 2;
        const byte NORMAL = 1;
        const byte SLOW = 0;

        public MainWindow()
        {
            InitializeComponent();

            alienTimer.Tick += alienTimer_Tick;
            alienTimer.Interval = TimeSpan.FromSeconds(2);

            hornAlienTimer.Tick += hornAlienTimer_Tick;
            hornAlienTimer.Interval = TimeSpan.FromSeconds(4);

            targetTimer.Tick += targetTimer_Tick;
            targetTimer.Interval = TimeSpan.FromSeconds(.1);

            progressBar.Maximum = 100; //10s

            oriHumanX = Canvas.GetLeft(human);
            oriHumanY = Canvas.GetTop(human);
            oriTargetX = Canvas.GetLeft(target);
            oriTargety = Canvas.GetTop(target);
        }

        void targetTimer_Tick(object sender, EventArgs e)
        {
            progressBar.Value += 1;
            if (progressBar.Value >= progressBar.Maximum)
                endTheGame();
        }

        void alienTimer_Tick(object sender, EventArgs e)
        {
            addAlien();
        }

        void hornAlienTimer_Tick(object sender, EventArgs e)
        {
            addHornAlien();
        }

        private void start_btn_Click(object sender, RoutedEventArgs e)
        {
            startGame();
        }

        private void startGame()
        {
            human.IsHitTestVisible = true;
            humanCaptured = false;

            progressBar.Value = 0;
            start_btn.Visibility = Visibility.Collapsed;

            countScore = 0;
            score.Text = "Score : 0" + countScore;

            Canvas.SetLeft(human, oriHumanX);
            Canvas.SetTop(human, oriHumanY);
            Canvas.SetLeft(target, oriTargetX);
            Canvas.SetTop(target, oriTargety);
            
            playArea.Children.Clear();
            playArea.Children.Add(target);
            playArea.Children.Add(human);

            alienTimer.Start();
            hornAlienTimer.Start();
            targetTimer.Start();
        }

        private void endTheGame()
        {
            if (!playArea.Children.Contains(resultText))
            {
                resultText.Text = "Game Over";
                start_btn.Content = "Restart";

                alienTimer.Stop();
                hornAlienTimer.Stop();
                targetTimer.Stop();

                humanCaptured = false;
                start_btn.Visibility = Visibility.Visible;
                playArea.Children.Add(resultText);
            }
        }

        private void winTheGame()
        {
            if (!playArea.Children.Contains(resultText))
            {
                resultText.Text = "You are Win";
                start_btn.Content = "Restart";

                alienTimer.Stop();
                hornAlienTimer.Stop();
                targetTimer.Stop();

                humanCaptured = false;
                start_btn.Visibility = Visibility.Visible;
                playArea.Children.Clear();
                playArea.Children.Add(resultText);

                ContentControl humanWin = new ContentControl();
                humanWin.Template = Resources["humanTemplate"] as ControlTemplate;

                Canvas.SetTop(humanWin, Canvas.GetTop(resultText) - 50);
                AnimateEnemy(humanWin, Canvas.GetLeft(resultText) + 50, resultText.ActualWidth - 80, "(Canvas.Left)", FAST);

                playArea.Children.Add(humanWin);
            }
        }

        private void addAlien()
        {
            ContentControl alien = new ContentControl();
            alien.Template = Resources["AlienTemplate"] as ControlTemplate;

            //Xuất hiện bên trái, và di chuyển qua phải, random về độ cao trong playArea
            AnimateEnemy(alien, 0, playArea.ActualWidth - 100, "(Canvas.Left)", NORMAL);
            AnimateEnemy(alien, random.Next((int)playArea.ActualHeight - 100),
                random.Next((int)playArea.ActualHeight - 100), "(Canvas.Top)", NORMAL);

            playArea.Children.Add(alien);
            alien.MouseEnter += alien_MouseEnter;
        }

        void alien_MouseEnter(object sender, MouseEventArgs e)
        {
            if (humanCaptured)
                endTheGame();
        }

        private void addHornAlien()
        {
            ContentControl hornAlien = new ContentControl();
            hornAlien.Template = Resources["hornAlienTemplate"] as ControlTemplate;

            //Xuất hiện ở 02 biên, và di chuyển random trong playArea

            double from = (random.Next((int)playArea.ActualWidth - 100) < ((int)playArea.ActualWidth - 100) / 2) ? 0 : (int)playArea.ActualWidth - 100;
            double to = (from == 0) ? (int)playArea.ActualWidth - 100 : 0;

            AnimateEnemy(hornAlien, from, to, "(Canvas.Left)", FAST);
            AnimateEnemy(hornAlien, random.Next((int)playArea.ActualHeight - 100),
                random.Next((int)playArea.ActualHeight - 100), "(Canvas.Top)", FAST);

            playArea.Children.Add(hornAlien);
            hornAlien.MouseEnter += hornAlien_MouseEnter;
        }

        void hornAlien_MouseEnter(object sender, MouseEventArgs e)
        {
            if (humanCaptured)
                endTheGame();
        }

        private void AnimateEnemy(ContentControl enemy, double from, double to, string propertyToAnimate, byte speed)
        {
            int spf = 0, spt = 0;

            switch (speed)
            {
                case SLOW:
                    spf = 6; spt = 10;
                    break;
                case NORMAL:
                    spf = 4; spt = 6;
                    break;
                case FAST:
                    spf = 1; spt = 4;
                    break;
            }

            Storyboard storyboard = new Storyboard()
            {
                AutoReverse = true,
                RepeatBehavior = RepeatBehavior.Forever
            };

            DoubleAnimation animation = new DoubleAnimation()
            {
                From = from, To = to, Duration = new Duration(TimeSpan.FromSeconds(random.Next(spf,spt)))
            };

            Storyboard.SetTarget(animation, enemy);
            Storyboard.SetTargetProperty(animation, new PropertyPath(propertyToAnimate));
            storyboard.Children.Add(animation);
            storyboard.Begin();
        }

        private void human_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (targetTimer.IsEnabled)
            {
                humanCaptured = true;
                human.IsHitTestVisible = false;
            }
        }

        private void playArea_MouseLeave(object sender, MouseEventArgs e)
        {
            if (humanCaptured)
                endTheGame();
        }

        private void playArea_MouseMove(object sender, MouseEventArgs e)
        {
            if (humanCaptured)
            {
                Point pointerPosition = e.GetPosition(null);
                Point relativePosition = grid.TransformToVisual(playArea).Transform(pointerPosition);

                if (Math.Abs(relativePosition.X - Canvas.GetLeft(human)) > human.ActualWidth * 3
                    || Math.Abs(relativePosition.Y - Canvas.GetTop(human)) > human.ActualHeight * 3)
                {
                    humanCaptured = false;
                    human.IsHitTestVisible = true;
                }
                else
                {
                    Canvas.SetLeft(human, relativePosition.X - human.ActualWidth / 2);
                    Canvas.SetTop(human, relativePosition.Y - human.ActualHeight / 2);
                }

            }
        }

        private void target_MouseEnter(object sender, MouseEventArgs e)
        {
            if (targetTimer.IsEnabled && humanCaptured)
            {
                countScore++;
                if (countScore >= winScore)
                {
                    score.Text = "Score : " + countScore.ToString();
                    winTheGame();
                }
                else
                {
                    progressBar.Value = 0;
                    score.Text = "Score : 0" + countScore.ToString();

                    Canvas.SetLeft(target, random.Next(100, (int)playArea.ActualWidth - 100));
                    Canvas.SetTop(target, random.Next(100, (int)playArea.ActualHeight - 100));

                    Canvas.SetLeft(human, random.Next(0, (int)playArea.ActualWidth - (int)human.ActualWidth));
                    Canvas.SetTop(human, random.Next(0, (int)playArea.ActualHeight - (int)human.ActualHeight));

                    int count = playArea.Children.Count;

                    if (count > 3)
                        for (int i = count; i > (count-2)/2 + 2; i--)
                        {
                            playArea.Children.RemoveAt(i - 1);
                        }

                    humanCaptured = false;
                    human.IsHitTestVisible = true;
                }

            }
        }

    }
}
